library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use IEEE.std_logic_arith.all;

entity linerenderer is
  port (next_line : in std_logic;
		next_screen : in std_logic;
		clk : in std_logic;
		hsync : in std_logic;
		
		-- output to line buffer
		addr_w : out std_logic_vector(8 downto 0);
		r_w : out std_logic_vector(7 downto 0);
		g_w : out std_logic_vector(7 downto 0);
		b_w : out std_logic_vector(7 downto 0);
		w_en : out std_logic;
		
		-- interface to memory of console buffer and color ram
		addr_r_color : out std_logic_vector(10 downto 0);
		addr_r_data : out std_logic_vector(10 downto 0);
		char_data : in std_logic_vector(7 downto 0);
		rgb_a : in std_logic_vector(23 downto 0);
		rgb_b : in std_logic_vector(23 downto 0);
		
		-- interface to character rom
		addr_read : out std_logic_vector(7 downto 0);
		char_line : out std_logic_vector(2 downto 0);
		char_line_data : in std_logic_vector(7 downto 0));
end linerenderer;

architecture rtl of linerenderer is
	signal ctr : integer;
	signal line_ctr : integer;
begin
	process(clk, next_line, next_screen)
		variable char_color_ctr : integer;
		variable char_console_ctr : integer;
	begin
		if (rising_edge(clk)) then
			if (next_screen = '1') then
				line_ctr <= 0;
			elsif (next_line = '1') then
				line_ctr <= line_ctr + 1;
				ctr <= 0;
			elsif (ctr <= 400) then
				ctr <= ctr + 1;
			end if;

			char_color_ctr := (line_ctr / 8) * 40 + ((ctr - 1) / 8);
			char_console_ctr := (line_ctr / 8) * 40 + (ctr / 8);

			-- read address for character from ram
			addr_r_data <= conv_std_logic_vector(char_console_ctr, 11);
			addr_r_color <= conv_std_logic_vector(char_color_ctr, 11);

			-- character data lookup in rom
			addr_read <= char_data;
			char_line <= conv_std_logic_vector(line_ctr, 3);
			
			-- writing result to line buffer
			addr_w <= conv_std_logic_vector((ctr - 3), 9);
			if (ctr >= 3 and ctr < 323) then
				w_en <= '1';
			else
				w_en <= '0';
			end if;

			if (char_line_data( 7 - (ctr - 3) mod 8 ) = '0') then
				r_w <= rgb_b(7 downto 0);
				g_w <= rgb_b(15 downto 8);
				b_w <= rgb_b(23 downto 16);
			else
				r_w <= rgb_a(7 downto 0);
				g_w <= rgb_a(15 downto 8);
				b_w <= rgb_a(23 downto 16);
			end if;
		end if;
	end process;
end rtl;
